package com.example.xcService.pojo.channels.impl;

import com.alibaba.fastjson.JSONObject;
import com.example.xcService.pojo.channels.ChannelResult;
import com.example.xcService.pojo.channels.ChannelService;
import com.example.xcService.pojo.tool.HttpTool;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;

/*
* QQ会员（MP活动接口）
* */
@Slf4j
public class Plugin_ECARD_P044 implements ChannelService {


    @Override
    public ChannelResult QueryBalance(JSONObject apiConfig) {
        System.out.println("成功调用了QueryBalance");
        return  ChannelResult.success("success");
    }

    @Override    public ChannelResult Submit(JSONObject apiConfig, Map<String, Object> data) {
        try {
            Integer appId = apiConfig.getInteger("AppId");
            String key = apiConfig.getString("SecretKey");
            String iv = apiConfig.getString("IV");
            String submitUrl = apiConfig.getString("SubmitUrl");

            String accountVal = String.valueOf(data.get("AccountVal"));
            String orderId = String.valueOf(data.get("ChannelOrderCode"));
            String productId = String.valueOf(data.get("SUPProductId"));

            Map<String, Object> submitParams = new HashMap<>();
            submitParams.put("appid",appId);
            submitParams.put("account_type",1);
            submitParams.put("account_id",accountVal);
            submitParams.put("cmd",productId);
            submitParams.put("order_id",orderId);
            if (checkQQNum(accountVal)){
                submitParams.put("src","qq");
            }else {
                submitParams.put("src","wx");
            }
            String sign = sortAndEncrypt(submitParams, key, iv);
            submitParams.put("sign",sign);
            String resStr = HttpTool.sendPost2(submitUrl, submitParams);
            JSONObject resObj = JSONObject.parseObject(resStr);
            String code = resObj.getString("ret");
            String msg = resObj.getString("msg");
            if (code.equals("0")||code.equals("10010")){
                return ChannelResult.success("充值成功");
            }
            /*  10001	传入的appid不存在	调整appid参数后重试
                10002	请求的cmd不存在	调整cmd参数后重试
                10003	请求解包失败	调整请求包后重试
                10004	签名解密失败	调整sign字段后重试
                10005	签名校验不一致	调整sign字段后重试
                10006	获取账号信息失败	调整accountType和accountId后重试
                10007	拉取用户会员信息失败	直接重试
                10008	会员状态异常，不发货	不重试，该用户无法兑换
                10009	校验发货状态失败	直接重试
                10010	订单已存在	不需要重试，该订单已发放成功
                10011	发货失败	发货失败，可以重试，原因较多，具体原因参考msg或联系wanderli协助排查
                */
            if (code.equals("10001")||code.equals("10002")
                    ||code.equals("10003")||code.equals("10004")
                    ||code.equals("10005")||code.equals("10006")
                    ||code.equals("10007")||code.equals("10009")
                    ||code.equals("10011")){
                return ChannelResult.error(msg);
            }
            return ChannelResult.FAILED(msg);
        }catch (Exception e) {
            e.printStackTrace();
            log.error("QQ会员（MP）提交订单接口错误：",e);
            return  ChannelResult.error("QQ会员（MP）提交订单接口错误");
        }
    }

    @Override
    public ChannelResult Query(JSONObject apiConfig, Map<String, Object> data) {
        return null;
    }


    @Override
    public ChannelResult Notify(JSONObject apiConfig, Map<String, Object> data) {
        System.out.println("成功调用了Notify");
        return  ChannelResult.success("success");
    }

    public static String sortAndEncrypt(Map<String, Object> requestBody,String secretKey,String IV) throws Exception {

        // 按照字典序升序排序
        String sortedQueryString = toSortedQueryString(requestBody);

        // 获取密钥和IV（这里仅为示例，实际中应从手Q增值后台获取）
        byte[] iv = IV.getBytes(StandardCharsets.UTF_8); // 初始化向量

        // 使用 AES/CBC/PKCS5PADDING 对称加密方式加密字符串，并对结果进行base64编码
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] encryptedBytes = cipher.doFinal(sortedQueryString.getBytes(StandardCharsets.UTF_8));
        String encryptedString = Base64.getEncoder().encodeToString(encryptedBytes);
        return encryptedString;
    }

    private static String toSortedQueryString(Map<String, Object> requestBody) {
        Map<String, String> sortedMap = new LinkedHashMap<>();
        requestBody.entrySet().stream()
                .sorted(Map.Entry.<String, Object>comparingByKey())
                .forEachOrdered(x -> sortedMap.put(x.getKey(), String.valueOf(x.getValue())));
        return String.join("&", sortedMap.entrySet().stream()
                .map(x -> x.getKey() + "=" + x.getValue())
                .collect(Collectors.toList()));
    }

    private static boolean checkQQNum(String s) {
        boolean flag = false;
        if (s.length() >= 5 && s.length() <= 15 && !s.startsWith("0")) {
            for (int i = 0; i < s.length(); i++) {
                char ch = s.charAt(i);
                if (ch >= '0' && ch <= '9') {
                    flag = true;
                } else {
                    flag = false;
                    break;
                }
            }
        }
        return flag;
    }

}
